<?php
// +----------------------------------------------------------------------
// | sfadmin - Suifeng Administration
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2020 http://suifeng.tech All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: suifeng <1787585212@qq.com>
// +----------------------------------------------------------------------

namespace suifeng\builder\form;

use suifeng\helper\BaseObject;
use suifeng\builder\form\Validator;
use suifeng\helper\HtmlHelper;
use suifeng\helper\ClassHelper;
use suifeng\helper\StringHelper;

class Control extends BaseObject
{
    /**
     * 表单对象。
     *
     * @var unknown
     */
    public $form;

    /**
     * 控件名称。
     *
     * @var unknown
     */

    public $name;

    /**
     * 控件值。
     *
     * @var unknown
     */
    public $value;

    /**
     * 标签提示。
     */
    public $label;

    /**
     * 错误信息。
     */
    public $error;

    /**
     * 帮助信息。
     */
    public $help;

    /**
     * 规则数组。
     *
     * @var array
     */
    public $rules;

    /**
     * 属性数组。
     *
     * @var array
     */
    public $attributes = array();

//     /**
//      * 提交的控件值。
//      *
//      * @var unknown
//      */
//     public $submitted_value;

    /**
     * 数据类型，默认是字符串。
     *
     * @var string
     */
    public $dbtype = 'string';

    /**
     * 构造方法。
     *
     * @param array $config
     */
    public function __construct($name, $config = array())
    {
        $this->name = $name;
        parent::__construct($config);

        if (empty($this->label)) {
            if (isset($config['title'])) {
                $this->label = $config['title'];
            } else {
                $this->label = StringHelper::friendly_text($this->name);
            }
        }
    }

    /**
     * 配置$rules属性。
     *
     * @param unknown $config
     */
    protected function _config_rules($config)
    {
        $this->rules = array();

        foreach ($config as $n => $rule) {
            if (is_array($rule)) {
                $validator = Validator::create($rule);
            } else if (is_string($rule)) {
                $validator = Validator::create(['rule' => $rule]);
            } else {
                $validator = $rule;
            }

            $validator->control =& $this;
            $validator->initialize();
            $this->rules[] = $validator;
        }
    }

//     /**
//      * 初始化控件。
//      */
//     public function initialize()
//     {
//         $this->_init_from_model();
//         $this->_parse_rules();
//         $this->_init_default();

//         if (empty($this->label)) {
//             $this->label = StringHelper::friendly_text($this->name);
//         }
//     }

//     /**
//      * 根据模型对象初始控件。
//      */
//     protected function _init_from_model()
//     {
//         if (empty($this->form->model)) {
//             return;
//         }

//         $field_info = $this->_get_field_info();

//         $alias_map = array(
//             'label' => ['title'],
//         );

//         $ref_class = new \ReflectionClass($this->form->model);

//         foreach (array_keys(get_object_vars($this)) as $key) {
//             if (empty($this->$key)) {
//                 $avalis = array_merge([$key], isset($alias_map[$key]) ? $alias_map[$key] : []);

//                 foreach ($avalis as $avail) {
//                     // 从字段定义获取属性值
//                     if (isset($field_info[$avail])) {
//                         $value = $field_info[$avail];
//                         if (! empty($value)) {
//                             $this->$key = $value;
//                             break;
//                         }
//                     }

//                     // 从FETCH方法获取属性值
//                     $method_name = "_fetch_control_{$avail}_for_{$this->name}";
//                     if ($ref_class->hasMethod($method_name)) {
//                         $ref_method = $ref_class->getMethod($method_name);
//                         $ref_method->setAccessible(true);
//                         $value = $ref_method->invoke($this->form->model);
//                         if (! empty($value)) {
//                             $this->$key = $value;
//                             break;
//                         }
//                     }
//                 }
//             }
//         }

//         // 字段默认规则
//         $field_rules = [];

//         // 必输字段
//         if (isset($field_info['required']) && $field_info['required']) {
//             $field_rules[] = ['rule' => 'required'];
//         }

//         // 字段长度
//         if (isset($field_info['dbtype']) &&
//             $field_info['dbtype'] == 'string' &&
//             isset($field_info['length']) && $field_info['length'] > 0) {
//             $field_rules[] = ['rule' => 'length', 'max' => intval($field_info['length'])];
//         }

//         $this->rules = array_merge($field_rules, (array) $this->rules);
//     }

//     /**
//      * 解析验证规则。
//      */
//     protected function _parse_rules()
//     {
//         if (empty($this->rules)) {
//             return;
//         }

//         foreach ($this->rules as $n => $rule) {
//             if (is_array($rule)) {
//                 $validator = Validator::create($rule);
//             } else if (is_string($rule)) {
//                 $validator = Validator::create(['rule' => $rule]);
//             } else {
//                 $validator = $rule;
//             }

//             $validator->control =& $this;
//             $validator->initialize();
//             $this->rules[$n] = $validator;
//         }
//     }

    public function parse_from_array($array)
    {
        $this->value = null;

        if (isset($array[$this->name])) {
            $value = $array[$this->name];

            if (is_array($value)) {
                foreach ($value as $key => $value) {
                    if (get_magic_quotes_gpc()) {
                        $value[$key] = stripslashes($value);
                    }
                }
            } else {
                if (get_magic_quotes_gpc()) {
                    $value = stripslashes($value);
                }
            }

            if ($this->dbtype && $value !== null) {
                $value = ClassHelper::convert_type($value, $this->dbtype);
            }

            $this->value = $value;
        }

        return $this->value;
    }

    /**
     * 验证控件数据。
     *
     * @return unknown
     */
    public final function validate()
    {
        $errors = array();

        if ($this->rules) {
            foreach ($this->rules as $rule) {
                if (! $rule->is_valid()) {
                    $errors += $rule->errors;
                    break; // 第一个验证器有错误，后面的验证器就不用再执行。
                }
            }
        }

        $this->error = implode('<br />', $errors);
        return empty($this->error);
    }

    /**
     * 数据是否有效？
     *
     * @return boolean
     */
    public final function is_valid()
    {
        return empty($this->error);
    }

//     /**
//      * 是否有验证错误？
//      *
//      * @return unknown
//      */
//     public final function has_error()
//     {
//         return !empty($this->error);
//     }

    /**
     * 输出HTML。
     *
     * @return string
     */
    public function render_html()
    {
        $html = $this->_render_core();
        if ($html) {
            $html .= $this->_render_help();
            $html .= $this->_render_error();
        }
        return $html;
    }

    public function __toString()
    {
        return $this->render_html();
    }

    /**
     * 输出核心信息。
     *
     * @return unknown|string
     */
    protected function _render_core()
    {
        return '';
    }

    /**
     * 输出帮助信息。
     *
     * @param unknown $help
     * @return unknown|string
     */
    protected function _render_help($help = null)
    {
        if ($help == null) {
            $help = $this->help;
        }

        if ($help) {
            return HtmlHelper::render_tag('span', ['class' => 'check-tips text-muted small'], $help);
        } else {
            return '';
        }
    }

    /**
     * 输出错误信息。
     *
     * @param unknown $error
     * @return unknown|string
     */
    protected function _render_error($error = null)
    {
        if ($error == null) {
            $error = $this->error;
        }

        if ($error) {
            return HtmlHelper::render_tag('span', ['class' => 'help-block'], $error);
        } else {
            return '';
        }
    }

    /**
     * 获取控件ID。
     *
     * @return string
     */
    protected function _get_control_id()
    {
        return StringHelper::var_name($this->form->name, $this->name);
    }

    protected function _get_formatted_name()
    {
        if (empty($this->form->array_name)) {
            return $this->name;
        } else {
            return $this->form->array_name . '[' . $this->name . ']';
        }
    }

    protected function _get_formatted_value()
    {
        return $this->value;
    }


    /**
     * 获取提交的控制值。
     *
     * @param unknown $array
     * @return \suifeng\form\controls\unknown
     */
    public function get_submitted_value($array)
    {
        $this->submitted_value = null;

        if (isset($array[$this->name])) {
            $value = $array[$this->name];

            if (is_array($value)) {
                foreach ($value as $key => $value) {
                    if (get_magic_quotes_gpc()) {
                        $value[$key] = stripslashes($value);
                    }
                }
            } else {
                if (get_magic_quotes_gpc()) {
                    $value = stripslashes($value);
                }
            }

            $this->submitted_value = $this->_parse_submitted_value($value);
        }

        return $this->submitted_value;
    }

    /**
     * 解析提交的控件值。
     *
     * @param unknown $value
     * @return unknown
     */
    protected function _parse_submitted_value($value)
    {
        $field_info = $this->_get_field_info();
        if (isset($field_info['dbtype'])) {
            return ClassHelper::convert_type($value, $field_info['dbtype']);
        } else {
            return $value;
        }
    }

    /**
     * 获取字段相关信息。
     *
     * @return array
     */
    public function _get_field_info()
    {
        if (isset($this->form->model->model_fields) &&
            array_key_exists($this->name, $this->form->model->model_fields)) {
                return $this->form->model->model_fields[$this->name];
            } else {
                return [];
            }
    }

    /**
     * 工厂方法。
     *
     * @return mixed
     */
    public static function create($type, $name, $config = array())
    {
        if (is_array($type)) {
            $config = $type;

            if (isset($config['control'])) {
                $type = $config['control'];
                unset($config['control']);
            } else {
                $type = 'text';
            }
        }

        $class_name = '\\suifeng\\html\\form\\control\\' . implode('', array_map('ucfirst', explode('_', $type)));
        if (!class_exists($class_name)) {
            throw new \Exception('Control type not exists: ' . $type);
        }

        $obj = new $class_name($name, $config);
        return $obj;
    }
}

?>